//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using OpenLS.Core.Serialization;

namespace OpenLS.Chart
{
    public class LineChart : LineChartBase
    {
        private Axis _firstAxis;
        private ChartLines _hiLowLines;
        private bool _marker;
        private Axis _secondAxis;
        private bool _smooth;
        private UpDownBars _upDownBars;

        public LineChart()
        {
            FirstAxis = new CategoryAxis();
            SecondAxis = new ValueAxis();
            FirstAxis.CrossAxis = SecondAxis;
            SecondAxis.CrossAxis = FirstAxis;
            _firstAxis.Position = AxisPosition.Bottom;
            _secondAxis.Position = AxisPosition.Left;
        }

        public DataSource Categories
        {
            get
            {
                if (Series.Count == 0)
                    return null;
                LineSeries firstSeries = Series[0];
                DataSource ds = firstSeries.Categories;
                if (ds == null)
                {
                    int count = GetDisplayInformation().Count;
                    return StringLiteral.NewStringLiteral(1, count);
                }
                return ds;
            }
        }


        public UpDownBars UpDownBars
        {
            get { return _upDownBars; }
            set
            {
                _upDownBars = value;
                notifyPropertyChanged("UpDownBars");
            }
        }


        public ChartLines HiLowLines
        {
            get { return _hiLowLines; }
            set
            {
                _hiLowLines = value;
                notifyPropertyChanged("HiLowLines");
            }
        }


        public bool Marker
        {
            get { return _marker; }
            set
            {
                if (_marker == value) return;
                _marker = value;
                notifyPropertyChanged("Marker");
            }
        }

        public bool IsSmooth
        {
            get { return _smooth; }
            set
            {
                if (_smooth == value) return;
                _smooth = value;
                notifyPropertyChanged("IsSmooth");
            }
        }

        internal Axis FirstAxis
        {
            get { return _firstAxis; }
            set
            {
                _firstAxis = value;
                notifyPropertyChanged("FirstAxis");
            }
        }

        internal Axis SecondAxis
        {
            get { return _secondAxis; }
            set { _secondAxis = value; }
        }

        public ValueAxis ValueAxis
        {
            get
            {
                var result = FirstAxis as ValueAxis;
                if (result != null)
                    return result;
                return SecondAxis as ValueAxis;
            }
        }

        [Obsolete]
        public Axis CategoryAxis
        {
            get { return HorizontalAxis; }
        }

        public Axis HorizontalAxis
        {
            get
            {
                Axis result = FirstAxis;
                switch (result.Position)
                {
                    case AxisPosition.Bottom:
                    case AxisPosition.Top:
                        return result;
                }
                return SecondAxis;
            }
        }

        public Axis VerticalAxis
        {
            get
            {
                Axis result = FirstAxis;
                switch (result.Position)
                {
                    case AxisPosition.Left:
                    case AxisPosition.Right:
                        return result;
                }
                return SecondAxis;
            }
        }

        protected override void VerifyAxes()
        {
            HorizontalAxis.CrossAxis = VerticalAxis;
            VerticalAxis.CrossAxis = HorizontalAxis;
        }

        internal override void ReadXmlCore(ReadContext context)
        {
            using (var c = context.Read("lineChart"))
            {
                ReadXmlBase(c);
                HiLowLines = c.ReadOptionalElementAs<ChartLines>("hiLowLines");
                UpDownBars = c.ReadOptionalElement<UpDownBars>("upDownBars");
                Marker = c.ReadOptionalElementBooleanAttribute("marker", false);
                IsSmooth = c.ReadOptionalElementBooleanAttribute("smooth", false);

                AxisResolver r = ReadContextData.GetAxisResolver(context);
                r.AddAction(c.ReadElementUIntegerAttribute("axId"),
                            delegate(Axis a) { FirstAxis = a; });

                r.AddAction(c.ReadElementUIntegerAttribute("axId"),
                            delegate(Axis a) { SecondAxis = a; });
                c.WarnIf("crtExt");
            }
        }

        internal override void WriteXmlCore(WriteContext context)
        {
            using (WriteContext c = context.Write("lineChart"))
            {
                WriteXmlBase(c);
                c.WriteOptionalElementAs(HiLowLines, "hiLowLines");
                c.WriteOptionalElement(UpDownBars);
                c.WriteOptionalElementBooleanAttribute("marker", Marker, false);
                c.WriteOptionalElementBooleanAttribute("smooth", IsSmooth, false);

                c.WriteElementUIntegerAttribute("axId", "val", FirstAxis.Id);
                c.WriteElementUIntegerAttribute("axId", "val", SecondAxis.Id);
                c.WarnIf("crtExt");
            }
        }

        internal override IEnumerable<Axis> GetAxes()
        {
            yield return FirstAxis;
            yield return SecondAxis;
        }
    }
}